package cn.epsilon3.interceptor;

import cn.epsilon3.common.E3BaseService;
import cn.epsilon3.constant.E3CacheKeyEnum;
import cn.epsilon3.mybatis.mapper.E3BlackIpMapper;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import cn.epsilon3.configBean.InitializingSecurityBlackListConfig;
import cn.epsilon3.constant.Base;
import cn.epsilon3.constant.ResultEnum;
import cn.epsilon3.domain.e3.po.E3BlackIpPo;
import cn.epsilon3.exception.Epsilon3ReturnException;
import cn.epsilon3.utils.HttpUtils;
import net.jodah.expiringmap.ExpiringMap;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.concurrent.TimeUnit;

/**
 * @description 黑名单ip拦截
 * @author: epsilon3
 * @date: 2023/9/5 23:26
 */
@Component
public class SecurityBlackListInterceptor extends E3BaseService implements HandlerInterceptor {

    private static final Log log = LogFactory.get();

    @Resource
    private E3BlackIpMapper blackIpMapper;

    @Resource
    private InitializingSecurityBlackListConfig blackListConfig;

    /**
     * 前置处理
     *
     * @param request
     * @param response
     * @param handler
     * @return
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        if (!blackListConfig.getEnable()) {
            return true;
        }
        String ip = HttpUtils.getIp(request);

        ExpiringMap<String, Integer> blackIpCache = getBlackIpCache();

        if (blackIpCache.containsKey(ip + E3CacheKeyEnum.BLACK_IP.getKey())) {
            throw new Epsilon3ReturnException(ResultEnum.OFTEN_REQ.getMessage());
        }

        Integer count = 0;
        if (blackIpCache.containsKey(ip)) {
            count = blackIpCache.get(ip);
        }
        Integer limitCount = blackListConfig.getCount();
        if (Base.INT0.equals(count)) {
            blackIpCache.put(ip, count + 1, blackListConfig.getCycleTime(), TimeUnit.SECONDS);
            return true;
        } else if (count <= limitCount) {
            blackIpCache.put(ip, count + 1);
            return true;
        } else {
            E3BlackIpPo e3BlackIpPo = new E3BlackIpPo();
            e3BlackIpPo.setCount(count);
            e3BlackIpPo.setIp(ip);
            blackIpMapper.insert(e3BlackIpPo);
            blackIpCache.put(ip + E3CacheKeyEnum.BLACK_IP.getKey(), count);
            log.error("{}单位时间内请求超过限制", ip);
            throw new Epsilon3ReturnException(ResultEnum.OFTEN_REQ.getMessage());
        }
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
    }


}

